#pragma once
#include <vector>
#include <string>
#include <algorithm>
#include <cstddef> // for size_t
#include <sys/types.h> // for ssize_t

namespace reactor {
/**
 * @brief 一个高效的缓冲区，用于网络IO
 */
class Buffer {
public:
    static const size_t kCheapPrepend = 8;
    static const size_t kInitialSize = 1024;

    explicit Buffer(size_t initialSize = kInitialSize)
        : _buffer(kCheapPrepend + initialSize),
          _readerIndex(kCheapPrepend),
          _writerIndex(kCheapPrepend) {}

    size_t readableBytes() const { return _writerIndex - _readerIndex; }
    size_t writableBytes() const { return _buffer.size() - _writerIndex; }
    size_t prependableBytes() const { return _readerIndex; }

    const char* peek() const { return begin() + _readerIndex; }

    void retrieve(size_t len) {
        if (len < readableBytes()) {
            _readerIndex += len;
        } else {
            retrieveAll();
        }
    }
    void retrieveAll() {
        _readerIndex = kCheapPrepend;
        _writerIndex = kCheapPrepend;
    }
    std::string retrieveAllAsString() {
        return retrieveAsString(readableBytes());
    }
    std::string retrieveAsString(size_t len) {
        std::string result(peek(), len);
        retrieve(len);
        return result;
    }

    void append(const char* data, size_t len) {
        ensureWritableBytes(len);
        std::copy(data, data + len, beginWrite());
        hasWritten(len);
    }
    
    // 从 fd 读取数据到缓冲区
    ssize_t readFd(int fd, int* savedErrno);

private:
    char* begin() { return &*_buffer.begin(); }
    const char* begin() const { return &*_buffer.begin(); }
    char* beginWrite() { return begin() + _writerIndex; }
    const char* beginWrite() const { return begin() + _writerIndex; }

    void hasWritten(size_t len) { _writerIndex += len; }
    void ensureWritableBytes(size_t len);
    void makeSpace(size_t len);

    std::vector<char> _buffer;
    size_t _readerIndex;
    size_t _writerIndex;
};
} // namespace reactor
